package ua.com.ulitko.client;

import com.google.gwt.cell.client.AbstractCell;
import com.google.gwt.cell.client.Cell;
import com.google.gwt.safehtml.shared.SafeHtmlBuilder;
import com.google.gwt.user.client.ui.HTML;
import com.google.gwt.view.client.ListDataProvider;
import com.google.gwt.view.client.SingleSelectionModel;
import com.google.gwt.view.client.TreeViewModel;
import ua.com.ulitko.client.entity.Album;
import ua.com.ulitko.client.entity.Performer;
import ua.com.ulitko.client.entity.Song;

import java.util.ArrayList;

/**
 * The model that defines the nodes in the tree.
 *
 * @author suamo ( 09.03.12 15:02 )
 */
public class CustomTreeModel implements TreeViewModel {

    /**
     * This selection model is shared across all leaf nodes. A selection model
     * can also be shared across all nodes in the tree, or each set of child
     * nodes can have its own instance. This gives you flexibility to determine
     * how nodes are selected.
     */
    private final SingleSelectionModel<Song> selectionModel = new SingleSelectionModel<Song>();

    /**
     * Get the {@link NodeInfo} that provides the children of the specified
     * value.
     */
    public <T> NodeInfo<?> getNodeInfo(T value) {
        if (value instanceof ArrayList && ((ArrayList) value).size() > 1 && ((ArrayList) value).get(0) instanceof Performer) {
            ListDataProvider<Performer> dataProvider = new ListDataProvider<Performer>((ArrayList<Performer>) value);
            Cell<Performer> cell = new AbstractCell<Performer>() {
                @Override
                public void render(Context context, Performer value, SafeHtmlBuilder sb) {
                    if (value != null) {
                        sb.appendEscaped(value.getName());
                    }
                }
            };

            return new DefaultNodeInfo<Performer>(dataProvider, cell);

        } else if (value instanceof Performer) {
            // LEVEL 1.
            // We want the children of the composer. Return the playlists.
            ListDataProvider<Album> dataProvider = new ListDataProvider<Album>(((Performer) value).getAlbumList());
            Cell<Album> cell = new AbstractCell<Album>() {
                @Override
                public void render(Context context, Album value, SafeHtmlBuilder sb) {
                    if (value != null) {
                        sb.appendEscaped(value.getName());
                    }
                }
            };
            return new DefaultNodeInfo<Album>(dataProvider, cell);
        } else if (value instanceof Album) {
            // LEVEL 2 - LEAF.
            // We want the children of the playlist. Return the songs.
            ListDataProvider<Song> dataProvider = new ListDataProvider<Song>(((Album) value).getSongList());
            Cell<Song> cell = new AbstractCell<Song>() {
                @Override
                public void render(Context context, Song value, SafeHtmlBuilder sb) {
                    if (value != null) {
                        sb.appendEscaped(value.getName());
                    }
                }
            };

            // Use the shared selection model.
            return new DefaultNodeInfo<Song>(dataProvider, cell, selectionModel, null);
        } else if (value instanceof Song) {
            HTML widget = new HTML(((Song) value).getText());
            ClientUtil.setToRightPanel(widget);
        }

        return null;
    }

    /**
     * Check if the specified value represents a leaf node. Leaf nodes cannot be
     * opened.
     */
    public boolean isLeaf(Object value) {
        // The leaf nodes are the songs, which are Strings.
        return false;
    }
}
